﻿using DongFangGuoKai.WMSPlatform.Core;
using DongFangGuoKai.WMSPlatform.Domain.Model;
using DongFangGuoKai.WMSPlatform.Service.InboundOrderDetail.DTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DongFangGuoKai.WMSPlatform.Service.InboundOrderDetail
{
    public partial class TReceivingOrderDetailService : ITReceivingOrderDetailService
    {
        private readonly SimpleRepositroy<TReceivingBills> receivingbillrepost;
        private readonly SimpleRepositroy<TReceivingBillDetails> receivingbillDteailrepost;
        private readonly SimpleRepositroy<TReceivingOrderDetails> receivingOrderDetailsrepost;
        private readonly SimpleRepositroy<TCells> cellrepost;
        private readonly SimpleRepositroy<TPallets> palletsrepost;
        private readonly SimpleRepositroy<TStackingStorages> stackingstoragesrepost;
        private readonly SimpleRepositroy<TInventories> inventoriesrepost;
        private readonly SimpleRepositroy<TInstructs> instructrepost;
        private readonly SimpleRepositroy<TPutawayOrders> putawayOrderrepost;
        private readonly SimpleRepositroy<TPackageDetails> packageDetailrepost;
        private readonly SimpleRepositroy<TInventoryDetails> inventoryDetailrepost;
        private readonly SimpleRepositroy<TPutawayOrderDetails> putawayOrderDetailrepost;
        private readonly SimpleRepositroy<TInventoryLogs> inventoryLogsrepost;
        private readonly SimpleRepositroy<TUpriverReceivingBills> upriverReceivingrepost;
        private readonly SimpleRepositroy<TUpriverReceivingBillsDetails> upriverReceivingDetailrepost;

        public TReceivingOrderDetailService(SimpleRepositroy<TReceivingBills> receivingbillrepost)
        {
            this.receivingbillrepost = receivingbillrepost;

            receivingbillDteailrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TReceivingBillDetails>>();
            receivingOrderDetailsrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TReceivingOrderDetails>>();
            cellrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TCells>>();
            stackingstoragesrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TStackingStorages>>();
            inventoriesrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TInventories>>();
            instructrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TInstructs>>();
            putawayOrderrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TPutawayOrders>>();
            packageDetailrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TPackageDetails>>();
            inventoryDetailrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TInventoryDetails>>();
            putawayOrderDetailrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TPutawayOrderDetails>>();
            inventoryLogsrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TInventoryLogs>>();
            palletsrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TPallets>>();
            upriverReceivingrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TUpriverReceivingBills>>();
            upriverReceivingDetailrepost = receivingbillrepost.ChangeRepository<SimpleRepositroy<TUpriverReceivingBillsDetails>>();
        }
        /// <summary>
        /// 查询验收单
        /// </summary>
        /// <param name="supplierId"></param>
        /// <param name="status"></param>
        /// <param name="warehouseId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public List<GetInOrderDTO> GetReceivingBillList(string? billNo, int status, int pageIndex, int pageSize, out int totalCount)
        {
            var list = receivingbillrepost.GetList();
            totalCount = list.Count();
            List<GetInOrderDTO> getInOrderDTOList = new List<GetInOrderDTO>();

            if (!string.IsNullOrEmpty(billNo))
            {
                list = list.Where(r => r.BillNo == billNo).ToList();
            }
            //查询状态
            if (status < 3)
            {
                list = list.Where(x => x.Status == status).ToList();
            }
            list = list.OrderByDescending(x => x.CreateDate).ToList();

            list = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            foreach (var item in list)
            {
                var rbd = receivingbillDteailrepost.GetList(r => r.BillId == item.Id).ToList();
                var rece = new GetInOrderDTO
                {
                    Id = item.Id,
                    BeginDate = item.BeginDate,
                    BillNo = item.BillNo,
                    CheckedQty = item.CheckedQty,
                    CreateUserId = item.CreateUserId,
                    CreateUserName = item.CreateUserName,
                    CreateDate = item.CreateDate,
                    BillDetailList = rbd,
                    ReceivedQTY = item.ReceivedQTY,
                    Status = item.Status,
                    TotalQty = item.TotalQty,
                    checkedAll = false
                };
                rece.ReceivedQTY = rbd.Sum(r => r.ReceivedQty);
                getInOrderDTOList.Add(rece);
            }
            return getInOrderDTOList;
        }

        /// <summary>
        /// 返回Excel验收单明细的数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public List<TReceivingBillDetails>? GetExcelData(int[] ids)
        {
            List<TReceivingBillDetails> receivingBillDetails = new();
            foreach (int id in ids) 
            {
                var receivingbillDteail = receivingbillDteailrepost.GetFirst(r=>r.Id == id);
                if (receivingbillDteail == null)
                {
                    return null;
                }
                receivingBillDetails.Add(receivingbillDteail);
            }
            return receivingBillDetails;
        }

        /// <summary>
        /// 显示入库单
        /// </summary>
        /// <param name="billType"></param>
        /// <param name="status"></param>
        /// <param name="warehouseid"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TReceivingOrderDetails> GetReceivingOrderDetailList(string orderSn, int billType, int status, int warehouseid, int pageIndex, int pageSize, out int totalCount)
        {
            var list = receivingOrderDetailsrepost.GetList();
            //入库单号
            if (!string.IsNullOrEmpty(orderSn))
            {
                list = list.Where(x => x.OrderSn.Contains(orderSn)).ToList();
            }

            if (billType != 0)
            {
                list = list.Where(x => x.BillType == billType).ToList();
            }

            if (status < 8)
            {
                list = list.Where(x => x.Status == status).ToList();
            }

            if (warehouseid != 0)
            {
                list = list.Where(x => x.WarehouseId == warehouseid).ToList();
            }

            totalCount = list.Count();

            list = list.OrderByDescending(x => x.CreateDate).ToList();

            return list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
        }

        /// <summary>
        /// PDA查询验收单
        /// </summary>
        /// <param name="supplierId"></param>
        /// <param name="status"></param>
        /// <param name="warehouseId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public List<GetInOrderDTO> PDAGetReceivingBillList(string? key, int pageIndex, int pageSize, out int totalCount)
        {
            var list = receivingbillrepost.GetList(r=>r.Status < 2);
            List<GetInOrderDTO> getInOrderDTOList = new List<GetInOrderDTO>();

            //是否根据单号查询
            if (!string.IsNullOrEmpty(key))
            {
                list = list.Where(r=>r.BillNo == key).ToList();
            }
            totalCount = list.Count();
            list = list.OrderByDescending(x => x.CreateDate).ToList();

            list = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            foreach (var item in list)
            {
                var rbd = receivingbillDteailrepost.GetList(r => r.BillId == item.Id).ToList();
                var rece = new GetInOrderDTO
                {
                    Id = item.Id,
                    BeginDate = item.BeginDate,
                    BillNo = item.BillNo,
                    CheckedQty = item.CheckedQty,
                    CreateUserId = item.CreateUserId,
                    CreateUserName = item.CreateUserName,
                    CreateDate = item.CreateDate,
                    BillDetailList = rbd,
                    ReceivedQTY = item.ReceivedQTY,
                    Status = item.Status,
                    TotalQty = item.TotalQty,
                    checkedAll = false
                };
                rece.ReceivedQTY = rbd.Sum(r => r.ReceivedQty);
                getInOrderDTOList.Add(rece);
            }
            return getInOrderDTOList;
        }

        /// <summary>
        /// 修改状态
        /// </summary>
        /// <param name="rid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdReceivingBillStatus(int rid)
        {
            var robj = receivingbillrepost.GetFirst(r=>r.Id == rid);
            if (robj != null)
            {
                robj.Status = 2;
                if (!receivingbillrepost.Update(robj))
                {
                    return false;
                }
                return true;
            }
            return false;
        }


        /// <summary>
        /// RFID添加验收单
        /// </summary>
        /// <param name="addReceivingBilDTO"></param>
        /// <returns></returns>
        public bool AddCheck(AddReceivingBilDTO addReceivingBilDTO, out string Message)
        {
            Message = "";
            try
            {
                receivingbillrepost.AsTenant().BeginTran();
                var rece = receivingbillrepost.GetFirst(r => r.BillNo == addReceivingBilDTO.BillNo);
                if (rece is not null)
                {
                    receivingbillrepost.AsTenant().RollbackTran();
                    Message = "有相同的验收单号";
                    return false;
                }
                TReceivingBills receivingBill = new TReceivingBills();
                //receivingBill.Id = addReceivingBilDTO.Id;
                receivingBill.CreateDate = DateTime.Now;
                receivingBill.BillNo = addReceivingBilDTO.BillNo;
                receivingBill.Status = 0;
                receivingBill.TotalQty = addReceivingBilDTO.addReceivingBilDetails.Sum(r => r.ReceivedQty);
                receivingBill.Id = receivingbillrepost.InsertReturnIdentity(receivingBill);
                if (receivingBill.Id <= 0)
                {
                    Message = "添加验收单失败！";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }

                foreach (var item in addReceivingBilDTO.addReceivingBilDetails)
                {
                    TReceivingBillDetails receivingBillDetail = new TReceivingBillDetails();
                    receivingBillDetail.BatchNo = item.BatchNo;
                    receivingBillDetail.BillNo = addReceivingBilDTO.BillNo;
                    receivingBillDetail.BillId = receivingBill.Id;
                    receivingBillDetail.MaterialCode = item.MaterialCode;
                    receivingBillDetail.MaterialName = item.MaterialName;
                    receivingBillDetail.Qty = item.ReceivedQty;
                    receivingBillDetail.ReceivedQty = 0;
                    receivingBillDetail.materialNorms = item.MaterialNorms;
                    receivingBillDetail.deptName = item.DeptName;
                    receivingBillDetail.checkInfoId = item.CheckInfoId;
                    receivingBillDetail.CreateDate = DateTime.Now;
                    if (!receivingbillDteailrepost.Insert(receivingBillDetail))
                    {
                        Message = "添加验收单明细失败！";
                        receivingbillrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }
                receivingbillrepost.AsTenant().CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                receivingbillrepost.AsTenant().RollbackTran();
                Message = "添加失败，" + ex.Message;
                return false;
            }
        }


        /// <summary>
        /// RFID添加收货单
        /// </summary>
        /// <param name="addReceivingBilDTO"></param>
        /// <returns></returns>
        public bool AddUpriverReceiving(AddReceivingBilDTO addReceivingBilDTO, out string Message)
        {
            Message = "";
            try
            {
                receivingbillrepost.AsTenant().BeginTran();
                var rece = upriverReceivingrepost.GetFirst(r => r.BillNo == addReceivingBilDTO.BillNo);
                if (rece is not null)
                {
                    receivingbillrepost.AsTenant().RollbackTran();
                    Message = "有相同的收货单号";
                    return false;
                }
                TUpriverReceivingBills UreceivingBill = new TUpriverReceivingBills();
                //receivingBill.Id = addReceivingBilDTO.Id;
                UreceivingBill.CreateDate = DateTime.Now;
                UreceivingBill.BillNo = addReceivingBilDTO.BillNo;
                UreceivingBill.Status = 0;
                UreceivingBill.TotalQty = addReceivingBilDTO.addReceivingBilDetails.Sum(r => r.ReceivedQty);
                UreceivingBill.Id = upriverReceivingrepost.InsertReturnIdentity(UreceivingBill);
                if (UreceivingBill.Id <= 0)
                {
                    Message = "添加收货单失败！";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }

                foreach (var item in addReceivingBilDTO.addReceivingBilDetails)
                {
                    TUpriverReceivingBillsDetails UreceivingBillDetail = new TUpriverReceivingBillsDetails();
                    UreceivingBillDetail.BatchNo = item.BatchNo;
                    UreceivingBillDetail.BillNo = addReceivingBilDTO.BillNo;
                    UreceivingBillDetail.BillId = UreceivingBill.Id;
                    UreceivingBillDetail.MaterialCode = item.MaterialCode;
                    UreceivingBillDetail.MaterialName = item.MaterialName;
                    UreceivingBillDetail.Qty = item.ReceivedQty;
                    UreceivingBillDetail.ReceivedQty = 0;
                    UreceivingBillDetail.materialNorms = item.MaterialNorms;
                    UreceivingBillDetail.deptName = item.DeptName;
                    UreceivingBillDetail.checkInfoId = item.CheckInfoId;
                    UreceivingBillDetail.CreateDate = DateTime.Now;
                    if (!upriverReceivingDetailrepost.Insert(UreceivingBillDetail))
                    {
                        Message = "添加收货单明细失败！";
                        receivingbillrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }
                receivingbillrepost.AsTenant().CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                receivingbillrepost.AsTenant().RollbackTran();
                Message = "添加失败，" + ex.Message;
                return false;
            }
        }


        /// <summary>
        /// 返回验收单下所有物料样品
        /// </summary>
        /// <param name="ChackNumber"></param>
        /// <returns></returns>
        public GetInOrderDTO? GetCheckMaterialCode(string ChackNumber)
        {
            var robj = receivingbillrepost.GetFirst(r => r.BillNo == ChackNumber);
            if (robj != null)
            {
                GetInOrderDTO getInOrder = new GetInOrderDTO();
                getInOrder.BillNo = robj.BillNo;
                getInOrder.Id = robj.Id;
                getInOrder.CreateDate = robj.CreateDate;
                var rbd = receivingbillDteailrepost.GetList(x => x.BillId == robj.Id);
                if (rbd != null)
                {
                    getInOrder.BillDetailList = rbd;
                    return getInOrder;
                }
                return getInOrder;
            }
            return null;
        }

        /// <summary>
        /// 修改收货单状态（已提交 海宁）
        /// </summary>
        /// <param name="checkNumber"></param>
        /// <param name="orderIds"></param>
        /// <returns></returns>
        public bool UpdateReceivingBillStatus(string checkNumber, string orderIds,out string Msg)
        {
            Msg = string.Empty;
            var res = receivingbillrepost.GetFirst(r => r.BillNo == checkNumber);
            if (res is null)
            {
                Msg = "未查询到验收单";
                return false;
            }
            var rids = orderIds.Split(',');
            receivingbillrepost.AsTenant().BeginTran();
            try
            {
                foreach (var rid in rids)
                {
                    var rdata = receivingOrderDetailsrepost.GetFirst(r => r.Id == Convert.ToInt32(rid));
                    if (rdata is null)
                    {
                        Msg = "未查出入库单";
                        receivingbillrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    rdata.Status = 9;
                    if (!receivingOrderDetailsrepost.Update(rdata))
                    {
                        Msg = "修改入库单失败!";
                        receivingbillrepost.AsTenant().RollbackTran();
                        return false;
                    };
                }
                var receorder = receivingOrderDetailsrepost.GetList(r => r.ReceivingBillId == res.Id && r.Status != 9).ToList();
                if (receorder.Count() <= 0 && res.Status == 2)
                {
                    res.Status = 3;
                    if (!receivingbillrepost.Update(res))
                    {
                        Msg = "修改收货单失败! 单号：" + checkNumber;
                        receivingbillrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }
                Msg = "修改状态成功!";
                receivingbillrepost.AsTenant().CommitTran();
                return true;

            }
            catch (Exception ex)
            {
                receivingbillrepost.AsTenant().RollbackTran();
                Msg = "修改收货单失败!" + ex.Message;
                return false;
            }
        }


        /// <summary>
        /// 获取提交入库的数据
        /// </summary>
        /// <returns></returns>
        public List<SubmitPutAwayDTO>? GetSubmitOutList()
        {
            var reces = receivingbillrepost.GetList(r => r.Status != 3 && r.Status != 0).OrderBy(r => r.CreateDate).ToList();
            if (reces is null)
            {
                return null;
            }
            List<SubmitPutAwayDTO> list = new List<SubmitPutAwayDTO>();
            foreach (var item in reces)
            {

                var rods = receivingOrderDetailsrepost.GetList(r => r.ReceivingBillId == item.Id && r.Status == 4);
                if (rods.Count <= 0)
                {
                    continue;
                }
                SubmitPutAwayDTO data = new SubmitPutAwayDTO()
                {
                    checkNumber = item.BillNo,
                    storeId = item.WarehouseId.GetValueOrDefault(),
                    userId = 2064
                };
                List<SubmitPutAwayDetailDTO> submitPutAwayDetailDTOs = new List<SubmitPutAwayDetailDTO>();
                foreach (var item2 in rods)
                {
                    submitPutAwayDetailDTOs.Add(new SubmitPutAwayDetailDTO()
                    {
                        count = item2.ReceivedQty.GetValueOrDefault(),
                        orderId = item2.Id,
                        storeLocationId = item2.storeLocationId,
                        remark = item2.Remark,
                        relationId = item2.relationId
                    });
                }
                data.items = submitPutAwayDetailDTOs;
                list.Add(data);
            }
            return list;
        }



        /// <summary>
        /// 生成入库单号
        /// </summary>
        /// <returns></returns>
        private string GetInOrderBarCode()
        {
            DateTime currentDateTime = DateTime.Now;
            string year = currentDateTime.ToString("yyyy");
            string month = currentDateTime.ToString("MM");
            string day = currentDateTime.ToString("dd");
            string hour = currentDateTime.ToString("HH");
            string minute = currentDateTime.ToString("mm");
            string second = currentDateTime.ToString("ss");
            Random random = new Random();
            string randomNumber = random.Next(1000000, 9999999).ToString();

            return $"{year}{month}{day}{hour}{minute}{second}{randomNumber}";
        }
    }
}
